home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-30 | 28.2 KB | 1,220 lines | [TEXT/MPS ] |
- /*
- File: PAPSample.cp
-
- Contains: Sample demonstration program for PAP
-
- Copyright: © 1993-1996 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #ifndef __OPENTPTGLOBALNEW__
- #include <OpenTptGlobalNew.h>
- #endif
- #ifndef __OPENTPTAPPLETALK__
- #include <OpenTptAppleTalk.h>
- #endif
- #ifndef __ATALKSAMPLEUTILS__
- #include "ATalkSampleUtils.h"
- #endif
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
- #ifndef __EVENTS__
- #include <Events.h>
- #endif
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- #define byName 1
- #define byAddr 0
-
- const size_t kMaxRecv = 5000; /*Max received data*/
- const size_t kMaxSend = 4096; /*Max send data*/
- UInt8 gIncomingBuffer[kMaxRecv];
-
- #if byName
- TNetbuf gDestName;
- #endif
-
- DDPAddress gSLSAddr;
- DDPAddress gConnAddr;
-
- const size_t kMaxReplyBufLen = (512 * 8) + 4;
-
- TEndpoint* gEp = NULL;
- TEndpoint* gStatusEp = NULL;
- Boolean gConnectFlag = false;
- OSStatus gConnectErr = 0;
- Boolean gFlowControl = false;
- Boolean gDone = false;
- Boolean gEOF = false;
- /*
- * We purposefully made gReadBuf not a multiple of 4K so that flow control
- * would be a little less nice
- */
- char gReadBuf[10000];
- char* gSendPtr;
- char* gReadPtr;
- size_t gBytesInBuf;
-
- OTLIFO gEventList;
-
- UInt16 gStatSequence = 0;
- Boolean gStatusAvailable = false;
- Boolean gReadyForStatus = true;
- Boolean gReceivedOrdRel = false;
- UInt8 gReplyBuffer[kMaxReplyBufLen];
- UInt8 gStatusBuffer[kMaxReplyBufLen];
- UInt8 gCurrentStatus[kMaxReplyBufLen]={0};
- size_t gStatusLen, gCurrentStatusLen;
- UInt32 gNextStatusTime = 0;
-
- /*******************************************************************************
- ** Structures
- ********************************************************************************/
-
- class TOTEventItem
- {
- public:
- inline TOTEventItem(void* ref, unsigned long code,
- OTResult result, void* cookie)
- {
- fRef = ref;
- fCode = code;
- fResult = result;
- fCookie = cookie;
- };
- OTLink fLink;
- void* fRef;
- unsigned long fCode;
- OTResult fResult;
- void* fCookie;
- };
-
- /*******************************************************************************
- ** Prototypes
- ********************************************************************************/
-
- pascal void EventHandler(void*, OTEventCode, OTResult, void*);
- OTResult DoReceive(TEndpoint*, unsigned char*);
- OTResult DoRequestStatus(TEndpoint *ep, Boolean useName = false);
- void DoReadUReplies(TEndpoint*);
- OSStatus DoReadData( FILE* fp);
- OSStatus PollEventList();
- OSStatus DoBind(TEndpoint* ep, unsigned char socket, unsigned char type);
- OSStatus DoConnect(TEndpoint* ep);
- OSStatus DoSend(TEndpoint* ep);
- TEndpoint* CreatePAPEndpoint();
- TEndpoint* CreateATPEndpoint();
- void DoTest();
-
- /*******************************************************************************
- ** EventHandler
- ** The event handler can be called at times when it is not safe to do console I/O,
- ** so this routine takes the event and jams it on a list to be handled when
- ** we know it's safe to print informative messages
- ********************************************************************************/
-
- pascal void EventHandler(void* contextPtr, OTEventCode code,
- OTResult result, void* cookie)
- {
- TOTEventItem* item = new TOTEventItem(contextPtr, code, result, cookie);
-
- if (item == NULL)
- {
- DebugStr("\pPAPTest: UniversalEventHandler -- could not allocate event structure");
- }
- else
- {
- gEventList.Enqueue(&item->fLink);
- }
- }
-
- /*******************************************************************************
- ** PollEventList
- ** This routine picks up the events received by EventHandler and processes them
- ********************************************************************************/
-
- OSStatus PollEventList()
- {
- OSStatus err = kOTNoError;
-
- if ( gStatusAvailable )
- {
- gReadyForStatus = true;
- gStatusAvailable = false;
- if ( gStatusLen > 0 )
- {
- if ( gCurrentStatusLen != gStatusLen ||
- !OTMemcmp(gCurrentStatus, gStatusBuffer + 8, gCurrentStatusLen) )
- {
- size_t offset = 1;
-
- /*
- * Handle the fact that most printers return a "pascal" string, even though
- * this is not required.
- */
- gCurrentStatusLen = gStatusLen;
- OTMemcpy(gCurrentStatus, gStatusBuffer + 8, gStatusLen);
- if ( gStatusBuffer[8] != gStatusLen - 1 )
- {
- DebugStr("\pPollEvenList = status not pascal string");
- offset = 0;
- }
- fprintf(stderr, "### Status: '%*.*s'\n", gCurrentStatusLen - offset, gCurrentStatusLen - offset,
- gCurrentStatus + offset);
- }
- }
- }
- while ( true )
- {
- OTLink* link = OTReverseList(gEventList.StealList());
-
- if ( link == NULL )
- break;
-
- while ( link != NULL )
- {
- TOTEventItem* item = OTGetLinkObject(link, TOTEventItem, fLink);
-
- link = link->fNext;
-
- OTResult result = item->fResult;
- void* cookie = item->fCookie;
- int epNum = (int)item->fRef;
- if (epNum < 0 || epNum > 1)
- {
- fprintf(stderr, "### Error: PollEventList, Got bad refnum in event record");
- delete item;
- continue;
- }
-
- TEndpoint* ep = epNum ? gStatusEp : gEp;
-
- switch (item->fCode )
- {
- case T_DATA:
- {
- OTResult result;
- fprintf(stderr, "### Info: Received Message from printer\n");
- while ( (result = DoReceive(ep, gIncomingBuffer)) >= 0 )
- {
- if ( result != 0 )
- fprintf(stderr, "### Msg: '%*.*s'\n", result, result, gIncomingBuffer);
- }
- break;
- }
-
- case T_CONNECT:
- {
- if ( result != 0 )
- {
- gConnectErr = result;
- err = result;
- break;
- }
- #if byName
- TCall rcvCall;
- rcvCall.addr.maxlen = sizeof gConnAddr;
- rcvCall.addr.buf = (UInt8*)&gConnAddr;
- rcvCall.opt.len = 0;
- rcvCall.udata.len = 0;
- err = ep->RcvConnect(&rcvCall);
- #endif
- #if byAddr
- err = ep->RcvConnect(NULL);
- #endif
- if ( err != kOTNoError && err != kOTNoDataErr )
- {
- DebugStr("\pPAPSample: RcvConnect returns an error!");
- gConnectErr = err;
- }
- else
- gConnectFlag = true;
-
- break;
- }
-
- case T_GODATA:
- {
- gFlowControl = false; // indicate that flow control has lifted
- fprintf(stderr, "### Info: flow control OFF\n");
- break;
- }
-
- case T_ORDREL:
- {
- err = ep->RcvOrderlyDisconnect();
- if ( err != kOTNoError )
- {
- DebugStr("\pRcvOrderlyDisconnect failed.;g");
- }
- gReceivedOrdRel = true;
- break;
- }
-
- case T_DISCONNECT:
- {
- if ( cookie != NULL ) // A connect is rejected
- {
- if ( !gConnectFlag )
- {
- DebugStr("\pConnection attempt failed. Doing RcvDisconnect.;g");
- ep->RcvDisconnect(NULL);
- gConnectErr = -2; // special constant
- }
- }
- break;
- }
-
- case T_REPLY :
- {
- DoReadUReplies(ep);
- break;
- }
-
- case T_DISCONNECTCOMPLETE:
- {
- gReceivedOrdRel = true;
- break;
- }
-
- default:
- {
- DebugStr("\pPAPSample: Unexpected Event!;g");
- break;
- }
- }
- }
- }
- return err;
- }
-
- /*******************************************************************************
- ** DoBind
- ********************************************************************************/
-
- OSStatus DoBind(TEndpoint* ep, unsigned char socket, unsigned char type)
- {
- OSStatus err = kOTNoError;
-
- DDPAddress addr;
- addr.Init(0, 0, socket, type); // Source address & type
-
- TBind req;
- req.addr.buf = (UInt8*)&addr;
- req.addr.len = kDDPAddressLength;
- req.qlen = 0;
-
- TBind ret;
-
- ret.addr.buf = (UInt8*)&addr;
- ret.addr.maxlen = sizeof(addr);
-
- fprintf(stderr, "### Info: Doing Bind\n");
- //
- // Try to bind
- //
- err = ep->Bind(&req, &ret);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "### Error: DoBind returns error %d\n", err);
- return err;
- }
-
- fprintf(stderr, "### Info: Bound address = ");
- ShowDDPAddress(&addr);
- fprintf(stderr, "\n");
- fprintf(stderr, "### Info: Bound queue len is %d\n", ret.qlen);
-
- fprintf(stderr, "### Info: After Bind, ");
- ShowEndpointState(ep, "");
-
- return err;
- }
-
- /*******************************************************************************
- ** DoConnect
- ********************************************************************************/
-
- OSStatus DoConnect(TEndpoint* ep)
- {
- TCall theCall;
- static unsigned char optbuf[3 * kOTFourByteOptionSize];
-
- #if byAddr
- theCall.addr.buf = (UInt8*)&gSLSAddr;
- theCall.addr.len = kDDPAddressLength;
- #endif
- #if byName
- theCall.addr.buf = gDestName.buf;
- theCall.addr.len = gDestName.len;
- #endif
-
- ((TOption*)optbuf)->len = kOTFourByteOptionSize;
- ((TOption*)optbuf)->level = ATK_PAP;
- ((TOption*)optbuf)->name = PAP_OPT_OPENRETRY;
- ((TOption*)optbuf)->value[0] = 10;
- (((TOption*)optbuf) + 1)->len = kOTFourByteOptionSize;
- (((TOption*)optbuf) + 1)->level = ATK_PAP;
- (((TOption*)optbuf) + 1)->name = OPT_INTERVAL;
- (((TOption*)optbuf) + 1)->value[0] = 500;
- #if 0
- (((TOption*)optbuf) + 2)->len = kOTFourByteOptionSize;
- (((TOption*)optbuf) + 2)->level = ATK_ATP;
- (((TOption*)optbuf) + 2)->name = ATP_OPT_REPLYCNT;
- (((TOption*)optbuf) + 2)->value[0] = 1;
- #endif
- theCall.opt.buf = (UInt8*)optbuf;
- #if 0
- theCall.opt.len = 3 * kOTFourByteOptionSize;
- #else
- theCall.opt.len = 2 * kOTFourByteOptionSize;
- #endif
- theCall.udata.len = 0;
-
- gConnectFlag = false;
- gConnectErr = 0;
- OSStatus err = ep->Connect(&theCall, NULL);
- if ( err != kOTNoError && err != kOTNoDataErr )
- {
- fprintf(stderr, "### Error: Connect() returns %d\n", err);
- if ( err == kOTLookErr )
- {
-
- fprintf(stderr, "### Info: Calling RcvDisconnect()...");
- OSStatus err = ep->RcvDisconnect(NULL);
- if ( err != kOTNoError )
- fprintf(stderr, "### Error: RcvDisconnect returned %d\n", err);
- }
- }
- else
- {
- err = kOTNoError;
- Boolean flag = false;
- while ( !gConnectFlag && !gConnectErr && !(flag = Button()) )
- {
- OTIdle();
- PollEventList();
- }
-
- if ( flag )
- err = -1; //%%% for now
- else
- err = gConnectErr;
- }
- return err;
- }
-
- /*******************************************************************************
- ** DoRead
- ********************************************************************************/
-
- OSStatus DoReadData(FILE* fp)
- {
- while ( !gEOF && gBytesInBuf < sizeof(gReadBuf) )
- {
- size_t toRead;
- size_t numRead;
-
- if ( gReadPtr >= gSendPtr )
- {
- toRead = gReadBuf + sizeof(gReadBuf) - gReadPtr;
- }
- else
- {
- toRead = gSendPtr - gReadPtr;
- }
- numRead = fread(gReadPtr, 1, toRead, fp);
- if ( numRead < 0 )
- {
- fprintf(stderr, "### Error: Error %d reading file\n", numRead);
- return (OSStatus)numRead;
- }
- printf("### Info: Read %d bytes\n", numRead);
- fflush(stdout);
- gBytesInBuf += numRead;
- gEOF = (numRead < toRead);
- gReadPtr += numRead;
- if ( gReadPtr >= gReadBuf + sizeof(gReadBuf) )
- {
- gReadPtr = gReadBuf;
- }
- }
- return kOTNoError;
- }
-
- /*******************************************************************************
- ** DoSend
- ********************************************************************************/
-
- OSStatus DoSend(TEndpoint* ep)
- {
- while ( gBytesInBuf > 0 )
- {
- size_t toSend;
- OTResult numSent;
-
- /*
- * If we're flow controlled or done, get out of here
- */
- if ( gFlowControl || gDone )
- return 0;
- /*
- * Set up the number of bytes we can send
- */
- if ( gSendPtr >= gReadPtr )
- {
- toSend = gReadBuf + sizeof(gReadBuf) - gSendPtr;
- }
- else
- {
- toSend = gReadPtr - gSendPtr;
- }
- /*
- * If there's nothing to send, get out of here, but handle
- * the special case where gReadPtr == gSendPtr and gBytesInBuf is
- * the sizeof(gReadBuf).
- */
- if ( toSend == 0 )
- {
- if ( gBytesInBuf != sizeof(gReadBuf) )
- {
- DebugStr("\pgBytesInBuf <> 0, but gReadPtr == gSendPtr");
- return 0;
- }
- toSend = gBytesInBuf;
- }
- /*
- * Send the data
- */
- numSent = ep->Snd(gSendPtr, toSend, 0);
- /*
- * TO make the logic easier, treat a flow error as a 0-byte send
- */
- if ( numSent == kOTFlowErr )
- numSent = 0;
- /*
- * If no error happened on the send, update everything
- */
- if ( numSent >= 0 )
- {
- gBytesInBuf -= numSent;
- /*
- * Update the send pointer
- */
- gSendPtr += numSent;
- if ( gSendPtr >= gReadBuf + sizeof(gReadBuf) )
- gSendPtr = gReadBuf;
- /*
- * Show progress
- */
- if ( numSent > 0 )
- {
- printf("### Info: Sent %d bytes\n", numSent);
- fflush(stdout);
- }
- /*
- * If we flow controlled, set the flags and split
- */
- if ( numSent < toSend )
- {
- gFlowControl = true;
- printf("### Info: flow control ON\n", ep);
- fflush(stdout);
- return 1;
- }
- /*
- * Set up the flag that says we're done
- */
- gDone = gEOF && gSendPtr == gReadPtr;
- continue;
- }
- /*
- * For a look error, we have to look - the only thing we should get is a T_DISCONNECT
- */
- if ( numSent == kOTLookErr )
- {
- OTResult look;
-
- look = ep->Look();
- switch ( look )
- {
- case T_DISCONNECT:
- {
- fprintf(stderr, "### Info: Got Look() returning T_DISCONNECT\n");
- look = ep->RcvDisconnect(NULL);
- if ( look < 0 )
- fprintf(stderr, "### Error: RcvDisconnect returned %d\n", look);
- else
- gConnectFlag = false;
- return -1;
- }
-
- default:
- fprintf(stderr, "### Error: Unexpected Look() return value - %d\n", look);
- return -3;
- }
- }
- /*
- * Here, we're clearly confused. Return a -2 to the caller so he can close things
- * down.
- */
- fprintf(stderr, "### ERROR: Snd fails with %d\n", numSent);
- return -2;
- }
- return kOTNoError;
- }
-
-
- /*******************************************************************************
- ** DoReceive
- ********************************************************************************/
-
- OTResult DoReceive(TEndpoint* ep, UInt8* buffer)
- {
- OTFlags flags = 0;
- OTResult result;
-
- result = ep->Rcv(buffer, kMaxRecv, &flags);
- if ( result < 0 )
- {
- if ( result == kOTLookErr )
- {
- OTResult look;
-
- look = ep->Look();
- switch ( look )
- {
- case T_DISCONNECT:
- {
- fprintf(stderr, "### Info: Got Look() returning T_DISCONNECT\n");
- look = ep->RcvDisconnect(NULL);
- if ( look < 0 )
- fprintf(stderr, "### Error: RcvDisconnect returned %d\n", look);
- else
- gConnectFlag = false;
- return -1;
- }
-
- default:
- fprintf(stderr, "### Error: Unexpected Look() return value - %d\n", look);
- return -3;
- }
- }
- else if ( result != kOTNoDataErr )
- {
- fprintf(stderr, "### Error: OTRcv() returned %d\n", result);
- }
- }
- return result;
- }
-
- /*******************************************************************************
- ** DoReadUReplies
- ********************************************************************************/
-
- void DoReadUReplies(TEndpoint* atpEp)
- {
-
- OSStatus err;
- OTFlags flags;
-
- while ( true )
- {
- TUnitReply reply;
-
- reply.opt.maxlen = 0;
- reply.udata.maxlen = sizeof(gStatusBuffer);
- reply.udata.buf = gStatusBuffer;
-
- err = atpEp->RcvUReply(&reply, &flags);
-
- if ( err != kOTNoError )
- {
- if ( err == kOTNoDataErr )
- return;
- if ( err != kETIMEDOUTErr )
- {
- fprintf(stderr, "\nOTRcvUReply: returned error %d\n", err);
- return;
- }
- }
- // If this is really the reply to our last request, save it.
- if ( reply.sequence == gStatSequence )
- {
- if ( reply.udata.len <= 8 )
- gStatusLen = 0;
- else
- {
- gStatusLen = (size_t)reply.udata.len - 8;
- }
- gStatusAvailable = true;
- }
-
- }
- }
-
- /*******************************************************************************
- ** CreatePAPEndpoint
- ********************************************************************************/
-
- TEndpoint* CreatePAPEndpoint()
- {
- TEndpoint* ep = NULL;
- OSStatus err = kOTNoError;
-
- do
- {
- //
- // Create a PAP
- //
- ep = OTOpenEndpoint(OTCreateConfiguration(kPAPName), 0, NULL, &err);
-
- if ( ep == NULL || err != kOTNoError )
- {
- ep = NULL;
- fprintf(stderr,"ERROR: OpenEndpoint(\"pap\") failed with %d\n", err);
- break;
- }
- ep->SetSynchronous();
-
- //
- // Install notifier we're going to use for testing
- //
- err = ep->InstallNotifier(EventHandler, NULL);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", err);
- break;
- }
-
- ShowFullEndpointData(ep);
-
- return ep;
-
- } while ( false );
-
- if ( ep != NULL )
- ep->Close();
-
- return NULL;
- }
-
- /*******************************************************************************
- ** CreateATPEndpoint
- ** Note that this will be a synchronous endpoint, so we don't need a notifier.
- ********************************************************************************/
-
- TEndpoint* CreateATPEndpoint()
- {
- TEndpoint* ep = NULL;
- OSStatus err = kOTNoError;
-
- do
- {
- //
- // Create a PAP
- //
- ep = OTOpenEndpoint(OTCreateConfiguration(kATPName), 0, NULL, &err);
-
- if ( ep == NULL || err != kOTNoError )
- {
- ep = NULL;
- fprintf(stderr,"ERROR: OpenEndpoint(\"atp\") failed with %d\n", err);
- break;
- }
- ep->SetSynchronous();
-
- //
- // Install notifier we're going to use for testing
- //
- err = ep->InstallNotifier(EventHandler, (void*)1);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", err);
- break;
- }
-
-
- return ep;
-
- } while ( false );
-
- if ( ep != NULL )
- ep->Close();
-
- return NULL;
- }
-
- /*******************************************************************************
- ** DoRequestStatus
- ********************************************************************************/
-
- OTResult DoRequestStatus(TEndpoint *ep, Boolean useName)
- {
- static UInt8 requestMsg[4] = {0, 8, 0, 0};
- static unsigned char optbuf[3 * kOTFourByteOptionSize];
-
- TUnitRequest theReq;
-
- if ( useName )
- {
- theReq.addr.buf = gDestName.buf;
- theReq.addr.len = gDestName.len;
- }
- else
- {
- theReq.addr.buf = (UInt8*)&gSLSAddr;
- theReq.addr.len = kDDPAddressLength;
- }
- //
- // We need to use the ATP_OPT_REPLY count option to specify that we're
- // only expecting a single packet response, because there are printers
- // out there that don't set the EOM bit when they should.
- //
- ((TOption*)optbuf)->len = kOTFourByteOptionSize;
- ((TOption*)optbuf)->level = ATK_ATP;
- ((TOption*)optbuf)->name = ATP_OPT_REPLYCNT;
- ((TOption*)optbuf)->value[0] = 1;
- (((TOption*)optbuf) + 1)->len = kOTFourByteOptionSize;
- (((TOption*)optbuf) + 1)->level = ATK_ATP;
- (((TOption*)optbuf) + 1)->name = OPT_RETRYCNT;
- (((TOption*)optbuf) + 1)->value[0] = 2; /* Retry 2 times */
- (((TOption*)optbuf) + 2)->len = kOTFourByteOptionSize;
- (((TOption*)optbuf) + 2)->level = ATK_ATP;
- (((TOption*)optbuf) + 2)->name = OPT_INTERVAL;
- (((TOption*)optbuf) + 2)->value[0] = 500; /* 500 milisecond retries */
-
- theReq.opt.buf = optbuf;
- theReq.opt.len = 3 * kOTFourByteOptionSize;
-
- theReq.udata.buf = requestMsg;
- theReq.udata.len = sizeof requestMsg;
-
- theReq.sequence = ++gStatSequence;
-
- gReadyForStatus = false;
- OTResult err = ep->SndURequest(&theReq, 0);
-
- gNextStatusTime = TickCount()+120; /* Next status in 2 seconds (allows for 1.5 seconds of retry time */
-
- if ( err != kOTNoError )
- fprintf(stderr, "SndURequest returns %d\n", err);
-
- return err;
- }
-
-
- /*******************************************************************************
- ** DoTest
- ********************************************************************************/
-
- void DoTest()
- {
- OSStatus err = kOTNoError;
- FILE *fp=NULL;
-
- do
- {
- /* -------------------------------------------------------------------------
- Create endpoint.
- ------------------------------------------------------------------------- */
-
- gEp = CreatePAPEndpoint();
- if ( gEp == NULL )
- {
- fprintf(stderr, "PAPSample: CreatePAPEndpoint for endpoint failed.\n", err);
- break;
- }
-
- #if 0
- {
- TOptMgmt opt1, opt2;
- TOption buf1, buf2;
- buf1.len = kOTFourByteOptionSize;
- buf1.level = XTI_GENERIC;
- buf1.name = XTI_RCVLOWAT;
- buf1.value[0] = 0;
- opt1.opt.buf = (UInt8*)&buf1;
- opt1.opt.len = kOTFourByteOptionSize;
- opt2.opt.maxlen = sizeof(TOption);
- opt2.opt.buf = (UInt8*)&buf2;
- opt1.flags = T_CURRENT;
- if ( (err = gEp->OptionManagement(&opt1, &opt2)) != kOTNoError )
- {
- fprintf(stderr, "PAPSample: get option failed (%d)\n", err);
- }
- else
- {
- fprintf(stderr, "PAPSample: Status value was %d, value = %d\n",
- buf2.status, buf2.value[0]);
- buf1.len = kOTFourByteOptionSize;
- buf1.level = XTI_GENERIC;
- buf1.name = XTI_RCVLOWAT;
- buf1.value[0] = 0xc000;
- opt1.flags = T_NEGOTIATE;
- if ( (err = gEp->OptionManagement(&opt1, &opt2)) != kOTNoError )
- {
- fprintf(stderr, "PAPSample: set option failed (%d)\n", err);
- }
- else
- {
- fprintf(stderr, "PAPSample: Status value was %d, value = %d\n",
- buf2.status, buf2.value[0]);
- }
- opt1.flags = T_CURRENT;
- if ( (err = gEp->OptionManagement(&opt1, &opt2)) != kOTNoError )
- {
- fprintf(stderr, "PAPSample: get option failed (%d)\n", err);
- }
- else
- {
- fprintf(stderr, "PAPSample: Status value was %d, value = %d\n",
- buf2.status, buf2.value[0]);
- }
-
- }
-
- }
- #endif
-
- /*-------------------------------------------------------------------------
- Bind endpoint.
- ------------------------------------------------------------------------- */
-
- UInt8 socket = 0;
- UInt8 type = 3;
-
- err = DoBind(gEp, socket, type);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "PAPSample: bind of PAP endpoint #1 failed.\n");
- break;
- }
-
- gEp->SetAsynchronous();
-
- /* -------------------------------------------------------------------------
- In order to get status from the printer, we have to use ATP. So let's open
- and ATP endpoint.
- ------------------------------------------------------------------------- */
-
- gStatusEp = CreateATPEndpoint();
- if ( gStatusEp == NULL )
- {
- fprintf(stderr, "PAPSample: CreateATPEndpoint for endpoint failed .\n", err);
- break;
- }
-
- /*-------------------------------------------------------------------------
- Bind status endpoint.
- ------------------------------------------------------------------------- */
-
- socket = 0;
- type = 3;
-
- err = DoBind(gStatusEp, socket, type);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "PAPSample: bind of ATP endpoint #1 failed.\n");
- break;
- }
-
- gStatusEp->SetAsynchronous();
-
- /* -------------------------------------------------------------------------
- Run the test.
- ------------------------------------------------------------------------- */
- do
- {
- char fileName[256];
- fprintf(stderr, "Enter name of input file:\n");
- while ( true )
- {
- gets(fileName);
- if ( fileName[0] != 0 )
- break;
- }
-
- fp = fopen(fileName, "r");
- if (fp == NULL)
- {
- fprintf(stderr, "Couldn't open file %s\n", fileName);
- break;
- }
-
- #if byName
- NBPAddress addr;
- char addrBuf[64];
-
- fprintf(stderr, "Enter name to send to in form 'name:type@zone'\n");
- while ( true )
- {
- gets(addrBuf);
- if ( addrBuf[0] != 0 )
- break;
- }
- gDestName.buf = (UInt8*)&addr;
- gDestName.len = addr.Init(addrBuf);
- {
- TBind inBind, outBind;
- inBind.addr.buf = gDestName.buf;
- inBind.addr.len = gDestName.len;
- outBind.addr.buf= (UInt8*)&gSLSAddr;
- outBind.addr.maxlen = kDDPAddressLength;
- gStatusEp->SetSynchronous();
- gStatusEp->SetBlocking();
- err = gStatusEp->ResolveAddress(&inBind, &outBind, 3000);
- if ( err != kOTNoError )
- {
- fprintf(stderr, "Could not find printer name\n");
- break;
- }
- gStatusEp->SetAsynchronous();
- }
- #endif
- #if byAddr
- int net, node, socket;
-
- fprintf(stderr, "Enter the target network: ");
- scanf("%x", &net);
- fprintf(stderr, "Enter the target node: ");
- scanf("%x", &node);
- fprintf(stderr, "Enter the target socket: ");
- scanf("%x", &socket);
-
- gSLSAddr.Init((UInt16)net, (UInt8)node, (UInt8)socket);
- fprintf(stderr, "Target net node socket: %.4x %.2x %.2x \n",net, node, socket);
- #endif
- //
- // Connect
- //
- gEp->SetAsynchronous();
- err = DoConnect(gEp);
- if ( err != kOTNoError )
- {
- if ( err == -2 )
- fprintf(stderr, "Connection attempt rejected\n");
- else
- fprintf(stderr, "DoConnect returned %d\n", err);
- break;
- }
- //
- // See what our status looks like
- //
- DoRequestStatus(gStatusEp);
-
-
- //
- // Try to Send some data
- //
- fprintf(stderr, "Copying File:\n");
-
- gFlowControl = false;
- gDone = false;
- /*
- * Start off our circular buffer
- */
- gSendPtr = gReadBuf;
- gReadPtr = gReadBuf;
- gBytesInBuf = 0;
-
- do
- {
- err = DoReadData(fp);
- if ( err < 0 )
- break;
-
- err = DoSend(gEp);
- if ( err < 0 )
- break;
-
- OTIdle();
- if ( gReadyForStatus && TickCount() >= gNextStatusTime)
- DoRequestStatus(gStatusEp);
- PollEventList();
- /*
- * gConnectFlag will get unset if we do an OTRcv() and
- * a Connect came in.
- */
- if ( !gConnectFlag )
- break;
-
- } while ( !gDone );
- fprintf(stderr, "\nWrite Complete\n");
-
- } while ( false );
-
- if ( gConnectFlag )
- {
- fprintf(stderr, "Press mouse to disconnect\n");
- while ( !Button() ) // Wait for mouse button
- {
- OTIdle();
- if (gReadyForStatus && TickCount() >= gNextStatusTime)
- DoRequestStatus(gStatusEp);
- PollEventList();
- }
- while ( Button() ) // Wait 'til it's released
- {
- OTIdle();
- if (gReadyForStatus && TickCount() >= gNextStatusTime)
- DoRequestStatus(gStatusEp);
- PollEventList();
- }
-
- //
- // Send Orderly Release
- //
- gEp->SetSynchronous();
- fprintf(stderr, "### Info: Sending orderly release\n");
- gReceivedOrdRel = false;
- err = gEp->SndOrderlyDisconnect();
- if ( err != kOTNoError )
- {
- if ( err == kOTLookErr )
- {
- OTResult look;
-
- fprintf(stderr,
- "### Info: SndOrderlyDisconnect returned a LOOK error\n");
-
- look = gEp->Look();
- switch ( look )
- {
- case T_DISCONNECT:
- {
- fprintf(stderr, "### Info: Got Look() returning T_DISCONNECT\n");
- look = gEp->RcvDisconnect(NULL);
- if ( look < 0 )
- fprintf(stderr, "### Error: RcvDisconnect returned %d\n", look);
- else
- gConnectFlag = false;
- break;
- }
-
- default:
- fprintf(stderr, "### Error: Unexpected Look() return value - %d\n", look);
- break;
- }
- }
- else
- {
- fprintf(stderr,
- "### Error: SndOrderlyDisconnect failed with %d\n", err);
- }
- }
- /*
- * If gConnectFlag is false - we got a Look while trying to disconnect and we're
- * disconnected by the underlying protocol, so don't wait for the orderly release
- */
- if ( gConnectFlag )
- {
- fprintf(stderr, "### Info: Waiting for orderly release acknowlegement - press mouse to abort\n");
- while( !gReceivedOrdRel && !Button() )
- {
- OTIdle();
- if (gReadyForStatus && TickCount() >= gNextStatusTime)
- DoRequestStatus(gStatusEp);
- PollEventList();
- }
- }
-
- ShowEndpointState(gEp, "");
-
- fprintf(stderr, "### Info: Press mouse to quit\n");
- while ( !Button() ) // Wait for mouse button
- {
- OTIdle();
- if (gReadyForStatus && TickCount() >= gNextStatusTime)
- DoRequestStatus(gStatusEp);
- PollEventList();
- }
- while ( Button() ) // Wait 'til it's released
- {
- OTIdle();
- if (gReadyForStatus && TickCount() >= gNextStatusTime)
- DoRequestStatus(gStatusEp);
- PollEventList();
- }
- }
-
-
- //
- // Unbind
- //
- fprintf(stderr, "### Info: About to Unbind()\n");
- err = gEp->Unbind();
- if ( err != kOTNoError )
- {
- fprintf(stderr, "### Error: Unbind(pap) returned %d\n", err);
- break;
- }
- ShowEndpointState(gEp, "");
-
- err = gStatusEp->Unbind();
- if ( err != kOTNoError )
- {
- fprintf(stderr, "### Error: Unbind(atp) returned %d\n", err);
- break;
- }
- ShowEndpointState(gStatusEp, "");
-
- } while (false);
-
- //
- // Get rid of endpoint.
- //
- if ( gStatusEp != NULL )
- {
- gStatusEp->RemoveNotifier();
- gStatusEp->Close();
- } //
- // Get rid of endpoint.
- //
- if ( gEp != NULL )
- {
- gEp->RemoveNotifier();
- gEp->Close();
- }
-
- //
- // close our file
- //
- if ( fp != NULL )
- fclose(fp);
-
- }
-
- /*******************************************************************************
- ** Initialize OpenTransport and call DoTest function
- ********************************************************************************/
-
- main(int, char**)
- {
- InitGraf(&qd.thePort); // initialize quickdraw so we can use regions
-
- fprintf(stderr, "PAPSample showing usage of PAP.\n\n");
- //
- // Initialize Open Transport
- //
- InitOpenTransport();
- //
- // Run the test
- //
- DoTest();
- //
- // Close Open Transport.
- // Not strictly necessary since it patches _ExitToShell and will
- // clean us up anyway.
- //
- CloseOpenTransport();
-
- fprintf(stderr, "\n\nDone\n");
-
- return 0;
- };
-
-